package com.lblin.method.body;

import com.lblin.method.annotation.Monitor;
import com.lblin.method.area.MethodUseArea;
import com.lblin.method.enums.MethodEnum;
import com.lblin.method.util.EunmUtil;

@Monitor
public abstract class BaseBody{
	
	/*create-enum*/
	
	/**
	 * 可用方法域
	 */
	protected MethodUseArea area = new MethodUseArea();
	
	/**
	 * 获取我所有可以执行的方法
	 * @return
	 */
	public MethodUseArea getMyMethod() {
		return area;
	} 

	/**
	 * 添加方法到可用方法域
	 * @param target 方法所在类
	 * @param methodName 方法名
	 * @param methodDesc 方法描述
	 */
	public void addMethod(String target,String methodName,String methodDesc) {
		
		String enumName = makeEnumName(target,methodName);
		EunmUtil.addEnum(MethodEnum.class, enumName,
				"String",target,
				"String",methodName,
				"String",methodDesc);
		
		area.getUseLink().put(MethodEnum.valueOf(enumName),null);//懒加载
		area.getUseMethod().put(MethodEnum.valueOf(enumName),null);//懒加载
		
	}
	
	/**
	 * 选择你要执行的方法
	 * @param target 方法所在目标类的全类名
	 * @param methodName 方法名（相同类中不允许方法名重复，不同参数的方法名也请命名为不同的名称）
	 * @param methodDesc 方法职责
	 * @return
	 */
	protected MethodEnum switchMethod(String target,String methodName) {
		return MethodEnum.valueOf(makeEnumName(target,methodName));
	}
	
	protected <T> MethodEnum switchMethod(T t) {
		return MethodEnum.valueOf(t.toString());
	}
	
	private static String makeEnumName(String className,String methodName) {
		return className+":"+methodName;
	}

	
	/**
	 * 通过传递方法类和方法名执行方法
	 * @param target
	 * @param methodName
	 * @param args
	 * @return
	 */
	public Object invokeMethod(Class<?> target,String methodName,Object ... args) {
		return switchMethod(target.getTypeName(),methodName).doMethod(this,args);
	}
	
	/**
	 * 通过传递枚举参数 执行方法（推荐使用）
	 * @param em
	 * @param args
	 * @return
	 */
	public <T> Object invokeMethod(T em,Object ... args){
		return switchMethod(em.toString()).doMethod(this,args);
	}
}
